package com.gcsoftware.gateway.GWImpl.xml;

import com.gcsoftware.gateway.GWImpl.GwAccessControl;
import com.gcsoftware.gateway.GWImpl.basics.dataProtection;
import com.gcsoftware.gateway.utils.TextUtils;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

/**
 * Created by yinpeng on 18/1/25.
 */
public class xmlDataProtection implements dataProtection
{
    private static final Logger log = LoggerFactory.getLogger(xmlDataProtection.class);
    private  Map<String ,Object> argsMap;

    public void setArgMap( Map<String ,Object> argsMap) {
        this.argsMap = argsMap;
    }

    private void getProtection(String nodeName, Element input ,Map<String, Object> rbacMap)
    {

            List<Element> listElement = input.elements();

            for (Element e : listElement) {
                log.debug("nodeName : [{}]" , e.getName());
//                System.out.println(nodeName + " ------ " + e.getName());
                //判断是否为xml  网传使用catch捕获异常效率最高
                if (StringUtils.isNotBlank(e.getText()) && e.getText().startsWith("<?xml")) {
                    log.debug("Element text start as xml.");
                    try {
                        Document doc = DocumentHelper.parseText(e.getText());
                        Element node = doc.getRootElement();
                        this.getProtection(node.getName(), node , rbacMap);
                        e.setText(doc.asXML());
                    } catch (Exception ex) {
                        log.error(ex.getMessage(),ex);
                    }
                } else {
                    if (e.elements().size() == 0) {
                        if (rbacMap.containsKey(e.getName()) ) {
                            if (StringUtils.isNotBlank(rbacMap.get(e.getName()).toString()) && !"null".equals(rbacMap.get(e.getName()).toString().toLowerCase())) {
                                e.setText(rbacMap.get(e.getName()).toString());
                            }
                        }
                    } else {
                        if (rbacMap.containsKey(e.getName()) && HashMap.class.getName().equals(rbacMap.get(e.getName()).getClass().getName())) {
                            this.getProtection(input.getName(), e , (Map<String, Object>) rbacMap.get(e.getName()));
                        } else {
                            this.getProtection(input.getName(), e , rbacMap);
                        }
                    }
                }


            }
            log.info("[{}][{}][{}][{}][{}][{}][{}][{}][{}]", argsMap.get("sourceIp"),argsMap.get("destinationIp"),argsMap.get("targetMethod"),argsMap.get("appId"), argsMap.get("token"),argsMap.get("roleId"), argsMap.get("roleName"),argsMap.get("senstiveIds"),argsMap.get("senstiveNames"));

    }

    public String protectExecute(String content , Map<String , Object> rbacMap) {
        String masker;
        try
        {
            Document doc = DocumentHelper.parseText(content);
            Element node = doc.getRootElement();
            long nanoStart = System.nanoTime();
            this.getProtection(node.getName(), node , rbacMap);
            long nanoEnd = System.nanoTime();
            log.info("It's takes [{}] ms times to get protection.",(nanoEnd - nanoStart)/1000000);
            masker = doc.asXML();
        }
        catch (Exception e)
        {
            log.warn(e.getMessage(),e);
//            e.printStackTrace();
            return content;
        }

        return masker;
    }

    public String protectExecute(String content , String charSet)
    {
        return protectExecute(content);
    }
    public String protectExecute(String content)
    {
        String masker;
        try
        {
            Document doc = DocumentHelper.parseText(content);
            Element node = doc.getRootElement();

            Map<String, Object>rbacMap = GwAccessControl.getAccessItemMap((String) argsMap.get("roleId"),(String)argsMap.get("endPoint"),(String)argsMap.get("targetMethod"),(String)argsMap.get("serviceId"));
            if (null != rbacMap && rbacMap.size() > 0)
                this.getProtection(node.getName(), node , rbacMap);

            masker = doc.asXML();

        }
        catch (Exception e)
        {
            e.printStackTrace();
            return content;
        }

        return masker;
    }


}
